#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <stdbool.h>

#define MAX_ROWS 10
#define MAX_COLS 10
int cols = 5; // Number of columns
// Function to print the current tableau
void printTableau(double tableau[MAX_ROWS][MAX_COLS], int rows, int cols) {
    printf("Current tableau:\n");
    for (int i = 0; i < rows; i++) {
        for (int j = 0; j < cols; j++) {
            printf("%.2f\t", tableau[i][j]);
        }
        printf("\n");
    }
    printf("\n");
}

// Function to find the pivot column
int findPivotColumn(double tableau[MAX_ROWS][MAX_COLS], int rows, int cols) {
    double min = tableau[0][0];
    int pivotColumn = 0;
    for (int j = 1; j < cols - 1; j++) {
        if (tableau[0][j] < min) {
            min = tableau[0][j];
            pivotColumn = j;
        }
    }
    return pivotColumn;
}

// Function to find the pivot row
int findPivotRow(double tableau[MAX_ROWS][MAX_COLS], int pivotColumn, int rows) {
    double minRatio = -1;
    int pivotRow = -1;
    for (int i = 1; i < rows; i++) {
        if (tableau[i][pivotColumn] > 0) {
            double ratio = tableau[i][cols - 1] / tableau[i][pivotColumn];
            if (minRatio == -1 || ratio < minRatio) {
                minRatio = ratio;
                pivotRow = i;
            }
        }
    }
    return pivotRow;
}

// Function to perform pivot operation
void pivot(double tableau[MAX_ROWS][MAX_COLS], int pivotRow, int pivotColumn, int rows, int cols) {
    double pivotValue = tableau[pivotRow][pivotColumn];
    // Update pivot row
    for (int j = 0; j < cols; j++) {
        tableau[pivotRow][j] /= pivotValue;
    }
    // Update other rows
    for (int i = 0; i < rows; i++) {
        if (i != pivotRow) {
            double factor = tableau[i][pivotColumn];
            for (int j = 0; j < cols; j++) {
                tableau[i][j] -= factor * tableau[pivotRow][j];
            }
        }
    }
}

// Function to check if optimality is reached
bool isOptimal(double tableau[MAX_ROWS][MAX_COLS], int cols) {
    for (int j = 1; j < cols - 1; j++) {
        if (tableau[0][j] < 0) {
            return false;
        }
    }
    return true;
}

// Simplex method implementation
void simplex(double tableau[MAX_ROWS][MAX_COLS], int rows, int cols) {
    while (!isOptimal(tableau, cols)) {
        int pivotColumn = findPivotColumn(tableau, rows, cols);
        int pivotRow = findPivotRow(tableau, pivotColumn, rows);
        if (pivotRow == -1) {
            printf("Unbounded solution\n");
            return;
        }
        pivot(tableau, pivotRow, pivotColumn, rows, cols);
        printTableau(tableau, rows, cols);
    }
}

int main() {
    // Linear programming problem:
    // Maximize z = 3x1 + 2x2
    // Subject to:
    // 2x1 + x2 <= 6
    // x1 + 2x2 <= 8
    // x1, x2 >= 0

    double tableau[MAX_ROWS][MAX_COLS] = {
        {-3.0, -2.0, 0.0, 0.0, 0.0},
        {2.0, 1.0, 1.0, 0.0, 6.0},
        {1.0, 2.0, 0.0, 1.0, 8.0}
    };

    int rows = 3; // Number of rows


    simplex(tableau, rows, cols);

    printf("Objective value: %.2f\n", -tableau[0][cols - 1]);
    printf("x1: %.2f\n", tableau[1][cols - 1]);
    printf("x2: %.2f\n", tableau[2][cols - 1]);

    return 0;
}
